﻿# CoffeeScript
@Cofe ?= {}
Link = Cofe.Link
MetadataList = Cofe.MetadataList

# MODEL - Represents a CofeWs Entry.
class Entry extends Spine.Model
  # id - identify the Entry in COFEFS.
  # label - display text.
  # path - full parse path.
  # basetype - "folder" or "file"
  # time - last write time in Date format, use @timeStr for string.
  # icon - icon image url.
  # length - file size.
  # subfoldercount - folder's sub-folder count. (optional)
  # filecount - folder's sub-file count. (optional)
  @configure 'Entry', 'id', 'label', 'path', 'type', 'time', 'links', 'length', 'data', 'metadata', 'md5'

  constructor: ->
    super

  # Uses to compare two entries, uses in sort or equals.
  compare : (anotherItem) ->    
    (if @type != anotherItem.type 
    then (if @type < anotherItem.type then -1 else 1) 
    else (if @path < anotherItem.path then -1 else 1))

  # Construct entry from cache using it's id, or return null if it's not cached.
  # full - fully loaded entry 
  Entry.fromId = (id, full) ->    
    if (full is true)
      entry = Entry.findByAttribute('id', id + "-full") 
    else entry = Entry.findByAttribute('id', id) 
    return (if entry is null or !entry.isValid then null else entry)
  
  Entry.fromPath = (path, full) ->
    entry = Entry.findByAttribute('path', path) 
    if entry isnt null
      return Entry.fromId(entry.id, full)
    return null

  Entry.remove = (id) ->
    e = Entry.fromId(id, false)
    eFull = Entry.fromId(id, true)
    if (e isnt null) then Entry.destroy(e.id)
    if (eFull isnt null) then Entry.destroy(eFull.id)

  Entry.invalidate = (entry) ->    
    if entry isnt null
      console.log "Invalidating " + entry.id
      if entry.links.list isnt undefined
        Cofe.EntryList.remove(entry.links.list.url)
      Entry.remove(entry.id)
  
  Entry.invalidatePath = (path) ->
    Entry.invalidate(Entry.fromPath(path))

  Entry.invalidateId = (id) ->
    Entry.invalidate(Entry.fromPath(id))

  Entry.fromUrl = (url) ->
    
    jsonData = $.ajax({
      type: 'GET'
      url: url
      dataType: 'json'
      success: () => 
      failed : () => 
      data: {}
      async: false
    })
    return Entry.fromJson($.parseJSON(jsonData.responseText))
  
  Entry.forRootEntry = () ->
    entry = new Entry({
      id : "2b5e670d-b375-4cb8-ab5a-243ffc2722b8"
      label : ""
      path : ""
      type : "directory"          
    })

    entry.links = [
      new Link("application/cofews.entrylist+xml", "List", 
        "/api/entry/2b5e670d-b375-4cb8-ab5a-243ffc2722b8/List")
    ]

    entry.save()
    return entry

  # Construct entry from COFEWS Entry json element.
  Entry.fromJson = (data, full) ->
    entry = Entry.fromId(data.id, full)
    if entry isnt null 
      return entry

    id = data.id
    if full is true
      id = data.id + "-full"

    entry = new Entry({
      id : id
      label : Cofe.utils.extractFilename(data.path)
      path : data.path
      type : data.type.toLowerCase()
      data : data
      links : {}
    })

    #entry.metadata = (new Object({key : d, value : data[d] }) for d of data when entry[d] is undefined)
    entry.metadata = new MetadataList(entry, data)
    #entry.metadata = new Array();
    #for d of data when entry[d] is undefined
    #  entry.metadata[d] = data[d]
    #console.log(entry.metadata)

    for link in data.links
      linkObj = Link.fromJson(link)
      entry.links[linkObj.rel] = linkObj
      if linkObj.rel is "typeInfo" and entry.icon is undefined
        entry.icon = linkObj.url + "?" + Cofe.iconUrlAtb
      else if linkObj.rel is "thumbnail" or linkObj.rel is "icon"
        entry.icon = linkObj.url + "?" + Cofe.defUrlAtb

    if (entry.isStream())
      entry.length = data.size
      entry.md5 = data.md5

    if entry.id isnt "00000000-0000-0000-0000-000000000000"
      entry.save()        
    entry   

  toJson : (exposedProps) =>
    entry = new Object()
    entry.id = @id.replace("-full", "")
    
    if exposedProps isnt undefined
      for p of @metadata
        switch p
          when "toString" then
          when "array" then
          when "text" then
          else 
            if p in exposedProps 
              entry[p] = @metadata[p]
    
    return entry

  isContainer : () ->
    'list' of @links

  isStream : () ->
    'stream' of @links

Entry.RootEntry = Entry.forRootEntry()
Cofe.Entry = Entry